package ;
import Files;
import HLex;
import HLlr;
import Macro;
import Main;
import Scope;
import Writer;





class Subs {
    public static function subs(data:Array<State>, macros:Array<Macro>, cscope:Scope) {
        var ret = [];

        
        
        var preidentc:String = null;
        var precons:Bool = false;
        
        
        var preident:String = null;
        for(x in data) {
            switch(x) {
                case sRealScope(s):
                    var macros = s.macros_in_scope();
                    s.data = subs(s.data,macros,s);
                     {
            var x = (x);
            ret.push(x);
        };
                    preident = null;
                case sIdent(n):
                    var macro =  {
            var found:Macro = null;
            for(i in macros) {
                if(i.argc==0 && i.name==n) {
                    found = i;
                    break;
                }
            }
            found;
        };
                    if(macro!=null) {
                        for(i in subs(macro.instantiate([],cscope), macros, cscope))
                             {
            var x = (i);
            ret.push(x);
        };
                        preident = null;
                    }else {
                        preident = n;
                         {
            var x = (x);
            ret.push(x);
        };
                    }
                case sCall(args):
                    var snd = true;
                    if(preident!=null) {
                        var macro =  {
            var found:Macro = null;
            for(i in macros) {
                if(i.argc==args.length && i.name==preident) {
                    found = i;
                    break;
                }
            }
            found;
        };
                        if(macro!=null) {
                            snd = false;
                            
                            ret.pop(); 
                            if(precons) { precons = false; }
                            else preidentc = null;
                            
                            for(i in subs(macro.instantiate(args,cscope),macros, cscope))
                                 {
            var x = (i);
            ret.push(x);
        };
                        }
                    }
                    if(snd) {
                        for(i in 0...args.length) args[i] = subs(args[i],macros,cscope);
                         {
            var x = (x);
            ret.push(x);
        };
                    }
                    preident = null;
                default:
                     {
            var x = (x);
            ret.push(x);
        };
                    preident = null;
            }
        }
        
        var ret2 = ret;
        ret = [];
        
        
        
        for(i in ret2)  {
            var x = (i);
            switch(x) {
                case sCons:
                    if(!precons) {
                        if(preidentc!=null)
                            precons = true;
                        ret.push(sCons);
                    }
                case sIdent(n):
                    if(precons && preidentc!=null) {
                        ret.pop(); ret.pop();
                        ret.push(sIdent(preidentc+=n));
                    }else {
                        ret.push(x);
                        preidentc = n;
                    }
                    precons = false;
                case sInteger(n):
                    if(precons && preidentc!=null) {
                        ret.pop(); ret.pop();
                        ret.push(sIdent(preidentc+=n));
                    }else ret.push(x);
                    precons = false;
                default:
                    precons = false;
                    preidentc = null;
                    ret.push(x);
            }
        };
        
        return ret;
    }
}
